#include <gtk/gtk.h>
#include <stdlib.h>
#include "main_win.h"
#include "digital.h"
#include "grid.h"

#define PIC_BG "pic/background"
#define PIC_BL "pic/background_black"
#define PIC_ST "pic/start"
#define PIC_EN "pic/end"
#define PIC_RU "pic/route"
#define PIC_SR "pic/start_route"
#define PIC_ER "pic/end_route"

#define PIXELS 48 
#define MAXNUM 15
#define MESG "行列值必须是大于1和小于16的整数！"
#define MESG2 "程序出现未知错误！"
#define MESG3 "没有找到一条可行的路径！"
#define MESG4 "请选择开始和结束点！"

static GtkWidget *window, *col_entry, *row_entry, *table, *vbox;
static int black = 0, point = 0, count = 0, clean = 0, again = 0;;
static int row = 0, col = 0;
struct node **grid, *grid_p[2];

static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data){
	return FALSE;
}

static void destroy(GtkWidget *widget, gpointer data){
	int i;
	for(i = 0; i < row; i++)
		free (grid[i]);
	free (grid);
	gtk_widget_destroy (table);

	gtk_widget_show (m_window);
	gtk_widget_hide (window);
}

/*点击“设置开始和结束“按钮是调用的函数*/
static void point_clicked(GtkWidget *widget, gpointer data){
	int i, j;
	if(again)
		for(i = 0; i < row; i++)
			for(j = 0; j < col; j++){
				if(grid[i][j].type != STOP){
					gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_BG);
					grid[i][j].start = 0;
					grid[i][j].end = 0;
					grid[i][j].type = NORM;
				}
			}
	again = 0;

	while(count){
		gtk_image_set_from_file (GTK_IMAGE(grid_p[--count]->image), PIC_BG);
		grid_p[count]->start = 0;
		grid_p[count]->end = 0;
	}
	
	clean = 0;
	black = 0;
	point = 1;
}

/*显示路径*/
static int display(struct node **grid, int row, int col){
	int i, j;

	for(i = 0; i < row; i++)
		for(j = 0; j < col; j++){
			if(grid[i][j].type == PICK)
				gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_RU);
			if(grid[i][j].start == 1)
				gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_SR);
			if(grid[i][j].end == 1)
				gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_ER);
		}
	return 0;	
}

/*开始处理，只是调用route（）函数*/
static void start_clicked(GtkWidget *widget, gpointer data){
	if(again)
		return ;
	GtkWidget *mesg;
	int retval = route(grid, row, col);

	if(retval == ERR){
		mesg = gtk_message_dialog_new ((GtkWindow *)window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE, MESG2);
		gtk_widget_show (mesg);
		return;
	}

	if(retval == FAIL){
		mesg = gtk_message_dialog_new ((GtkWindow *)window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE, MESG3);
		gtk_widget_show (mesg);
		return;
	}

	if(retval == NOTFOUND){
		mesg = gtk_message_dialog_new ((GtkWindow *)window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE, MESG4);
		gtk_widget_show (mesg);
		return;
	}

	display(grid, row, col);
	again = 1;
}

/*设置障碍*/
static void stop_clicked(GtkWidget *widget, gpointer data){
	int i, j;
	if(again)
		for(i = 0; i < row; i++)
			for(j = 0; j < col; j++){
				if(grid[i][j].type != STOP){
					gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_BG);
					grid[i][j].start = 0;
					grid[i][j].end = 0;
					grid[i][j].type = NORM;
				}
			}
	again = 0;

	while(point == 1 && count){
		gtk_image_set_from_file (GTK_IMAGE(grid_p[--count]->image), PIC_BG);
		grid_p[count]->start = 0;
		grid_p[count]->end = 0;
	}

	clean = 0;	
	black = 1;
	point = 0;
}

/*清除障碍*/
static void clean_clicked(GtkWidget *widget, gpointer data){
	int i, j;
	if(again)
		for(i = 0; i < row; i++)
			for(j = 0; j < col; j++){
				if(grid[i][j].type != STOP){
					gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_BG);
					grid[i][j].start = 0;
					grid[i][j].end = 0;
					grid[i][j].type = NORM;
				}
			}
	again = 0;

	while(point == 1 && count){
		gtk_image_set_from_file (GTK_IMAGE(grid_p[--count]->image), PIC_BG);
		grid_p[count]->start = 0;
		grid_p[count]->end = 0;
	}

	clean = 1;
	black = 0;
	point = 0;
}

static void flash_clicked(GtkWidget *widget, gpointer data){
	int i, j;
	for(i = 0; i < row; i++)
		for(j = 0; j < col; j++){
			gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_BG);
			grid[i][j].start = 0;
			grid[i][j].end = 0;
			grid[i][j].distance = 0;
			grid[i][j].type = NORM;
		}
	clean = 0;
	black = 0;
	point = 0;

	again = 0;
}

/*格子点击时调用的函数，分别判断什么按钮按下*/
static void grid_clicked(GtkWidget *widget, GdkEvent  *event, gpointer data){
	int i, j;
	for(i = 0; i < row; i++)
		for(j = 0; j < col; j++)
			if(grid[i][j].event_box == widget)
				goto out;
	return;
	out:
	/*设障碍*/
	if(black == 1){
		if(grid[i][j].start == 1 || grid[i][j].end == 1)
			return ;

		gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_BL);

		grid[i][j].start = 0;
		grid[i][j].end = 0;
		grid[i][j].type = STOP;
		return;
	}

	/*清障碍*/
	if(clean == 1){
		if(grid[i][j].start == 1 || grid[i][j].end == 1)
			return ;

		gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_BG);

		grid[i][j].start = 0;
		grid[i][j].end = 0;
		grid[i][j].type = NORM;
		return;
	}

	/*设起点和终点*/
	if(point == 1){
		if(count == 0){
			grid_p[0] = &(grid[i][j]);

			gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_ST);

			grid[i][j].start = 1;
			grid[i][j].end = 0;
			grid[i][j].type = NORM;
			count++;
			return;
		}
		if(count == 1){
			if(grid[i][j].start == 1)
				return;
			grid_p[1] = &(grid[i][j]);

			gtk_image_set_from_file (GTK_IMAGE(grid[i][j].image), PIC_EN);

			grid[i][j].start = 0;
			grid[i][j].end = 1;
			grid[i][j].type = NORM;
			count++;
			point = 0;
			return;
		}
	}
}

/*显示表格*/
static GtkWidget *creat_grid(int row, int col){
	GtkWidget *table, *button;
	int i, j, num, left_attach = 0, right_attach = 1, top_attach = 0, bottom_attach = 1;

	grid = (struct node **)malloc (sizeof(struct node *) * row);

	for(i = 0; i < row; i++)
		grid[i] = (struct node *)malloc (sizeof(struct node) * col);

	table = gtk_table_new (row, col, TRUE);

	num = row*col;
	for(i= 0; i < row; i++){
		for(j = 0; j < col; j++){
			grid[i][j].start = 0;
			grid[i][j].end = 0;
			grid[i][j].distance = 0;
			grid[i][j].type = NORM;

			grid[i][j].image = gtk_image_new_from_file (PIC_BG);
			grid[i][j].event_box = gtk_event_box_new ();

			gtk_container_add (GTK_CONTAINER (grid[i][j].event_box), grid[i][j].image);
			gtk_widget_show (grid[i][j].image);

			gtk_widget_set_events (grid[i][j].event_box, GDK_BUTTON_PRESS_MASK);
			g_signal_connect (grid[i][j].event_box, "button_press_event", G_CALLBACK (grid_clicked), NULL);

			gtk_table_attach (GTK_TABLE(table), grid[i][j].event_box, left_attach, right_attach, top_attach,\
					bottom_attach,0,0,0,0);
			gtk_widget_show (grid[i][j].event_box);

			/*计算位置*/
			left_attach = (left_attach+1) % col;
			right_attach += 1;
			if(left_attach == 0){
				right_attach = 1;
				top_attach += 1;
				bottom_attach += 1;
			}
		}
	}
	again = 0;
	return table;
}

/*重新设置表格*/
static void set_clicked(GtkWidget *widget, gpointer data){
	GtkWidget *mesg;
	char *col_str, *row_str;
	int c, r, i, n = 0;

	black = 0;
	point = 0;
	count = 0;

	col_str = (char *)gtk_entry_get_text (GTK_ENTRY (col_entry));
	c = digital (col_str, &n);
	n = 0;
	row_str = (char *)gtk_entry_get_text (GTK_ENTRY (row_entry));
	r = digital (row_str, &n);

	if(c <= 1 || col > MAXNUM || r <= 1 || row > MAXNUM){
		mesg = gtk_message_dialog_new ((GtkWindow *)window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE, MESG);
		gtk_widget_show (mesg);
		return;
	}

	for(i = 0; i < row; i++)
		free (grid[i]);
	free (grid);
	gtk_widget_destroy (table);

	table = creat_grid (row = r, col = c);
	gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
	gtk_widget_show (table);
}

/*界面，代码很多，不过都是机械性的代码*/
int grid_win(void){
	GtkWidget *col_label, *row_label, *set_button, *point_button, *stop_button, *clean_button, *start_button, *flash_button, *hbox1, *hbox2;

	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title (GTK_WINDOW(window), GRID);
	gtk_window_set_position (GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
	gtk_window_set_icon_from_file (GTK_WINDOW(window), LOGO, NULL);
	gtk_window_set_default_size (GTK_WINDOW(window), 1, 1);
	gtk_window_set_resizable (GTK_WINDOW(window), FALSE);

	g_signal_connect (window, "delete-event", G_CALLBACK (delete_event), NULL);
	g_signal_connect (window, "destroy", G_CALLBACK (destroy), NULL);

	col_label = gtk_label_new ("请输入列数：");
	col_entry = gtk_entry_new();

	row_label = gtk_label_new ("请输入行数：");
	row_entry = gtk_entry_new();

	set_button = gtk_button_new_with_label ("设置");
	g_signal_connect (set_button, "clicked", G_CALLBACK (set_clicked), NULL);

	point_button = gtk_button_new_with_label ("设置起点和终点");
	g_signal_connect (point_button, "clicked", G_CALLBACK (point_clicked), NULL);

	stop_button = gtk_button_new_with_label ("设置障碍");
	g_signal_connect (stop_button, "clicked", G_CALLBACK (stop_clicked), NULL);
	
	clean_button = gtk_button_new_with_label ("清除障碍");
	g_signal_connect (clean_button, "clicked", G_CALLBACK (clean_clicked), NULL);

	flash_button = gtk_button_new_with_label ("刷新");
	g_signal_connect (flash_button, "clicked", G_CALLBACK (flash_clicked), NULL);

	start_button = gtk_button_new_with_label ("开始");
	g_signal_connect (start_button, "clicked", G_CALLBACK (start_clicked), NULL);

	hbox1 = gtk_hbox_new (FALSE, 0);
	hbox2 = gtk_hbox_new (FALSE, 0);
	vbox = gtk_vbox_new (FALSE, 0);

	gtk_box_pack_start (GTK_BOX (hbox1), col_label, FALSE, FALSE, 0);
	gtk_widget_show (col_label);

	gtk_box_pack_start (GTK_BOX (hbox1), col_entry, FALSE, FALSE, 0);
	gtk_widget_show (col_entry);

	gtk_box_pack_start (GTK_BOX (hbox1), row_label, FALSE, FALSE, 0);
	gtk_widget_show (row_label);

	gtk_box_pack_start (GTK_BOX (hbox1), row_entry, FALSE, FALSE, 0);
	gtk_widget_show (row_entry);

	gtk_box_pack_start (GTK_BOX (hbox1), set_button, FALSE, FALSE, 0);
	gtk_widget_show (set_button);

	gtk_box_pack_start (GTK_BOX (vbox), hbox1, FALSE, FALSE, 0);
	gtk_widget_show (hbox1);

	gtk_box_pack_start (GTK_BOX (hbox2), point_button, FALSE, FALSE, 0);
	gtk_widget_show (point_button);

	gtk_box_pack_start (GTK_BOX (hbox2), stop_button, FALSE, FALSE, 0);
	gtk_widget_show (stop_button);

	gtk_box_pack_start (GTK_BOX (hbox2), clean_button, FALSE, FALSE, 0);
	gtk_widget_show (clean_button);

	gtk_box_pack_start (GTK_BOX (hbox2), flash_button, FALSE, FALSE, 0);
	gtk_widget_show (flash_button);

	gtk_box_pack_start (GTK_BOX (hbox2), start_button, FALSE, FALSE, 0);
	gtk_widget_show (start_button);

	gtk_box_pack_start (GTK_BOX (vbox), hbox2, FALSE, FALSE, 0);
	gtk_widget_show (hbox2);

	table = creat_grid (row = 10, col = 10);
	gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
	gtk_widget_show (table);

	gtk_container_add (GTK_CONTAINER (window), vbox);
	gtk_widget_show (vbox);

	gtk_widget_show (window);

	return 0;
}
